/*
 * @Copyright: Copyright (c) 2030 吴周海
 * @Author: wzh200x@126.com
 * @Date: 2025-10-09 14:00:15
 * @LastEditors: wzh200x@126.com
 * @LastEditTime: 2025-10-09 14:13:45
 * @FilePath: \goWebServer\goGameWebServer\internal\common\database\baseDataBase.go
 * @Description: 文件功能描述
 */
package database

import (
	"context"
	"database/sql"
	"goGameWebServer/internal/common/config"
	"goGameWebServer/internal/common/database/entityHelper"

	"github.com/gogf/gf/v2/container/garray"
	"github.com/gogf/gf/v2/container/gmap"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
)

type BaseDataBase struct {
	ctx               context.Context
	Options           config.DatabaseOption
	EntityData        *gmap.StrAnyMap
	ModuleShareFields *gmap.StrAnyMap
	EntityModule      *gmap.StrAnyMap
}

func NewBaseDateBase(ctx context.Context, option config.DatabaseOption) BaseDataBase {
	return BaseDataBase{
		ctx:               ctx,
		Options:           option,
		EntityData:        gmap.NewStrAnyMap(),
		ModuleShareFields: gmap.NewStrAnyMap(),
		EntityModule:      gmap.NewStrAnyMap(),
	}
}

func (base *BaseDataBase) SyncTable() error {
	//TODO implement me
	return nil
}

func (base *BaseDataBase) Init() {
	gdb.AddConfigNode(base.Options.GroupName, base.Options.ConfigNode)
}

func (base *BaseDataBase) Name() string {
	return base.Options.Name
}

func (base *BaseDataBase) GroupName() string {
	return base.Options.GroupName
}

func (base *BaseDataBase) GetDb() gdb.DB {
	return g.DB(base.Options.GroupName)
}

func (base *BaseDataBase) GetPrefix() string {
	return base.Options.Prefix
}

func (base *BaseDataBase) SaveDataWithMap(data gdb.Map, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Save()
}

func (base *BaseDataBase) SaveDataWithStruct(data interface{}, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Save()
}

func (base *BaseDataBase) SaveMultiDataWithListMap(data gdb.List, batch int, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	if batch > 0 {
		return base.GetDb().Model(tableNameOrStruct...).Data(data).Batch(batch).Save()
	}
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Save()
}

func (base *BaseDataBase) InsertDataWithMap(data gdb.Map, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Insert()
}

func (base *BaseDataBase) InsertDataWithStruct(data interface{}, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Insert()
}

func (base *BaseDataBase) InsertDataWithListMap(data gdb.List, batch int, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	if batch > 0 {
		return base.GetDb().Model(tableNameOrStruct...).Data(data).Batch(batch).Insert()
	}
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Insert()
}

func (base *BaseDataBase) InsertDataWithMapAndGetId(data gdb.Map, tableNameOrStruct ...interface{}) (lastInsertId int64, err error) {
	return base.GetDb().Model(tableNameOrStruct...).Data(data).InsertAndGetId()
}

func (base *BaseDataBase) InsertDataWithStructAndGetId(data interface{}, tableNameOrStruct ...interface{}) (lastInsertId int64, err error) {
	return base.GetDb().Model(tableNameOrStruct...).Data(data).InsertAndGetId()
}

func (base *BaseDataBase) ReplaceDataWithMap(data gdb.Map, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Replace()
}

func (base *BaseDataBase) ReplaceDataWithStruct(data interface{}, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Replace()
}

func (base *BaseDataBase) ReplaceDataWithListMap(data gdb.List, batch int, tableNameOrStruct ...interface{}) (result sql.Result, err error) {
	if batch > 0 {
		return base.GetDb().Model(tableNameOrStruct...).Data(data).Batch(batch).Replace()
	}
	return base.GetDb().Model(tableNameOrStruct...).Data(data).Replace()
}

func (base *BaseDataBase) UpdateEntityData(entityName string, entityData *entityHelper.DBEntity) {
	base.EntityData.Set(entityName, entityData)
}

func (base *BaseDataBase) GetEntityData(entityName string) *entityHelper.DBEntity {
	return base.EntityData.Get(entityName).(*entityHelper.DBEntity)
}

func (base *BaseDataBase) CheckEntityIsExist(entityName string) bool {
	return base.EntityData.Contains(entityName)
}

func (base *BaseDataBase) GetEntityDatas() *gmap.StrAnyMap {
	return base.EntityData
}

func (base *BaseDataBase) AppendModuleShareField(shareField *entityHelper.DBEntityField) {
	base.ModuleShareFields.Set(shareField.FieldName, shareField)
}

func (base *BaseDataBase) GetModuleShareFields() []interface{} {
	return base.ModuleShareFields.Values()
}

func (base *BaseDataBase) CheckModuleShareField(fieldName string) bool {
	return base.ModuleShareFields.Contains(fieldName)
}

func (base *BaseDataBase) AppendModuleName(entityName string, moduleName string) {
	if !base.EntityModule.Contains(entityName) {
		base.EntityModule.Set(entityName, garray.New())
	}
	base.EntityModule.Get(entityName).(*garray.Array).Append(moduleName)
}

func (base *BaseDataBase) CheckModuleExist(entityName string, moduleName string) bool {
	if !base.EntityModule.Contains(entityName) {
		return false
	}
	return base.EntityModule.Get(entityName).(*garray.Array).Contains(moduleName)
}
